package com.hippo.javacore.multithreading;

/**
 * @ClassName ThreadDemo10
 * @Description TODO 线程安全/线程同步--同步方法
 * @Author tangxl
 * @create 2023-03-14 11:39
 **/
public class ThreadDemo10 implements Runnable {

    // 票数
    // S:考虑为什么这里不加static?
    // 因为实现Runnable的类是作为一个参数传给Thread的，这里所有线程共享一个ThreadDemo9对象，所以不需要static
    int ticket = 0;

    @Override
    public void run() {
        // 1、循环
        while (true) {
            // 2、同步代码块（同步方法）
            synchronized (ThreadDemo9.class){
                if (method()) {
                    break;
                }
            }

        }
    }

    private synchronized boolean method() {
        // 3、判断共享数据是否到了末尾，如果没有到末尾
        if (ticket < 100) {
            try {
                // 模拟网络延迟
                Thread.sleep(10);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            ticket++;
            System.out.println("@"+Thread.currentThread().getName() + "卖出了第" + ticket + "张票");
        }
        // 4、判断共享数据是否到了末尾，如果到了末尾
        else {
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        /**
         * 需求：某电影院的观众席有100张座位，现在有3个窗口同时售票，请设计一个程序模拟该售票过程
         * 同步方法完成
         */
        // 创建Runnable接口的实现类对象
        Runnable runnable = new ThreadDemo10();

        // 创建线程
        Thread t1 = new Thread(runnable);
        Thread t2 = new Thread(runnable);
        Thread t3 = new Thread(runnable);

        // 线程命名
        t1.setName("窗口1");
        t2.setName("窗口2");
        t3.setName("窗口3");

        // 线程执行
        t1.start();
        t2.start();
        t3.start();

    }
}
